import pandas as pd
import numpy as np
from sklearn.preprocessing import StandardScaler
from sklearn.model_selection import train_test_split
from sklearn.tree import DecisionTreeRegressor
from sklearn.naive_bayes import GaussianNB
from sklearn.svm import SVR
from sklearn.neural_network import MLPRegressor
from sklearn.model_selection import GridSearchCV
from sklearn.metrics import mean_squared_error

# 创建数据框
data = {
    '债券简称': ['G21苏林1', 'G21综能1', 'G21华新1', 'G21华新2', '21北电', 'PR文1A1', 'PR文1A2',
                 'PR文1B', 'GC华能04', 'GC太科01', '21昆明轨道', 'G苏天2优', 'G苏天2次'],
    '计划发行规模（亿）': [2.0000, 10.0000, 10.0000, 10.0000, 5.0000, 2.5200, 2.8000,
                         0.9800, 20.0000, 1.0000, 10.0000, 10.1200, 0.5300],
    '发行金额上限（亿）': [2.0000, 10.0000, 10.0000, 10.0000, np.nan, np.nan, np.nan,
                         np.nan, 20.0000, 1.0000, 15.0000, np.nan, np.nan],
    '债券评级': [np.nan, 'AA+', 'AAA', 'AAA', np.nan, 'AAA', 'AAA', 'AA+', 'AAA', 'AA', 'AAA', 'AAA', np.nan]
}

df = pd.DataFrame(data)

# 判断是否存在缺失值
has_missing_values = df.isnull().values.any()
print("是否存在缺失值：", has_missing_values)

# 处理缺失值
df.fillna(value={'发行金额上限（亿）': 0, '债券评级': '未评级'}, inplace=True)

# 特征选择
X = df[['计划发行规模（亿）']]
y = df['发行金额上限（亿）']

# 数据标准化
scaler = StandardScaler()
X = scaler.fit_transform(X)

# 划分数据集
X_train, X_val_test, y_train, y_val_test = train_test_split(X, y, test_size=0.2, random_state=42)
X_val, X_test, y_val, y_test = train_test_split(X_val_test, y_val_test, test_size=0.5, random_state=42)

# 决策树
parameters = {'max_depth': [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]}
dt = DecisionTreeRegressor(random_state=42)
clf = GridSearchCV(dt, parameters, cv=5)
clf.fit(X_train, y_train)
print("决策树最佳参数：", clf.best_params_)

# 训练模型
dt = DecisionTreeRegressor(max_depth=clf.best_params_['max_depth'], random_state=42)
dt.fit(X_train, y_train)

# 预测
y_pred_dt = dt.predict(X_val)

# 评估模型
mse_dt = mean_squared_error(y_val, y_pred_dt)
print("决策树在验证集上的均方误差 (MSE)：", mse_dt)

# 在测试集上评估模型
y_pred = dt.predict(X_test)
mse = mean_squared_error(y_test, y_pred)
print("决策树在测试集上的均方误差 (MSE)：", mse)

# 贝叶斯
gnb = GaussianNB()
gnb.fit(X_train, y_train)

# 预测
y_pred_gnb = gnb.predict(X_val)

# 评估模型
mse_gnb = mean_squared_error(y_val, y_pred_gnb)
print("贝叶斯在验证集上的均方误差 (MSE)：", mse_gnb)

# 输出最佳参数
print("贝叶斯没有超参数需要调整，因此没有最佳参数。")

# 在测试集上评估模型
y_pred = gnb.predict(X_test)
mse = mean_squared_error(y_test, y_pred)
print("贝叶斯在测试集上的均方误差 (MSE)：", mse)

# SVM
parameters = {'kernel': ['linear', 'rbf', 'poly', 'sigmoid'],
              'C': [0.1, 1, 10, 100],
              'gamma': ['scale', 'auto']}
svm = SVR()
clf = GridSearchCV(svm, parameters, cv=5)
clf.fit(X_train, y_train)
print("SVM最佳参数：", clf.best_params_)

# 训练模型
svm = SVR(kernel=clf.best_params_['kernel'], C=clf.best_params_['C'], gamma=clf.best_params_['gamma'])
svm.fit(X_train, y_train)

# 预测
y_pred_svm = svm.predict(X_val)

# 评估模型
mse_svm = mean_squared_error(y_val, y_pred_svm)
print("SVM在验证集上的均方误差 (MSE)：", mse_svm)

# 在测试集上评估模型
y_pred = svm.predict(X_test)
mse = mean_squared_error(y_test, y_pred)
print("SVM在测试集上的均方误差 (MSE)：", mse)

import matplotlib.pyplot as plt

# 模型性能比较
models = ['Decision Tree', 'Naive Bayes', 'SVM']
mse_scores = [mse_dt, mse_gnb, mse_svm]

plt.figure(figsize=(10, 6))
plt.bar(models, mse_scores, color=['blue', 'green', 'red'])
plt.xlabel('Model')
plt.ylabel('Mean Squared Error (MSE)')
plt.title('Model Performance Comparison')
plt.show()
